package com.guodi.model.service.impl;

import com.guodi.common.config.NacosCustomConfig;
import com.guodi.common.utils.HttpRequester;
import com.guodi.common.utils.MDUtil;
import com.guodi.core.mp.base.BaseServiceImpl;
import com.guodi.core.tool.api.R;
import com.guodi.core.tool.utils.DigestUtil;
import com.guodi.core.tool.utils.SpringUtil;
import com.guodi.model.entity.Org;
import com.guodi.model.entity.User;
import com.guodi.model.entity.UserOrg;
import com.guodi.model.entity.UserRole;
import com.guodi.model.mapper.UserMapper;
import com.guodi.model.service.IOrgService;
import com.guodi.model.service.IUserOrgService;
import com.guodi.model.service.IUserRoleService;
import com.guodi.model.service.IUserService;
import com.guodi.model.vo.ApiCimUser;
import com.guodi.system.dto.OrgDTO;
import com.guodi.system.feign.IRegionClient;
import com.guodi.system.feign.IRoleClient;
import com.guodi.system.vo.OrgVO;
import com.guodi.system.vo.RegionVO;
import com.guodi.system.vo.RoleVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Objects;

@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {

    //默认角色
    private static String DEFAULT_ROLE_CODE = "user";
    //默认密码
    private static String DEFAULT_USER_PWD = "2@jrD5Qq9";
    //刷新缓存接口
    private static String DEFAULT_REFRESH_REDIS = "/sys-system/redis/refreshRedis";

    @Resource
    private UserMapper userMapper;
    @Resource
    private IRoleClient iRoleClient;
    @Resource
    private IRegionClient iRegionClient;
    @Resource
    private IUserOrgService iUserOrgService;
    @Resource
    private IUserRoleService iUserRoleService;
    @Resource
    private IOrgService iOrgService;

    /**
     * @描述: 保存cim平台同步过来的用户
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 16:30
     **/
    @Override
    public void saveCimUser(ApiCimUser cimUser) {
        User saveEntity = new User();
        BeanUtils.copyProperties(cimUser,saveEntity);
        saveEntity.setUserCode(cimUser.getAccount());
        //备用字段1用来记录用户是cim平台同步过来的用户
        saveEntity.setMemo1("cim_user");
        Integer maxSort = userMapper.getMaxSort("SYS_USER");
        saveEntity.setSort(maxSort + 1);
        //设置默认密码
        saveEntity.setPassword(getPassword());

        //查部门，如果不存在，需要新建
        OrgDTO orgVO = getOrgByRegionCode(cimUser.getRegionCode());
        saveEntity.setUnitId(orgVO.getUnitId());
        boolean saveUser = this.save(saveEntity);
        cimUser.setUserId(saveEntity.getId());

        //保存用户机构关系
        UserOrg userOrg = new UserOrg();
        userOrg.setUserId(saveEntity.getId());
        userOrg.setOrgId(orgVO.getId());
        boolean saveUserOrg = iUserOrgService.save(userOrg);

        //保存用户角色关系
        R<RoleVO> roleVOR = iRoleClient.findByRoleCode(DEFAULT_ROLE_CODE);
        Long roleId = roleVOR.getData().getId();
        UserRole userRole = new UserRole();
        userRole.setUserId(saveEntity.getId());
        userRole.setRoleId(roleId);
        boolean saveUserRole = iUserRoleService.save(userRole);

        boolean ret = saveUser && saveUserOrg && saveUserRole;
        if(ret){
            refreshRedis();
        }
    }

    /**
     * @描述: 更新用户信息
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 16:33
     **/
    @Override
    public void editCimUser(ApiCimUser cimUser, User user) {
        Long userId = user.getId();
        cimUser.setAccount(null);
        cimUser.setUserId(userId);
        BeanUtils.copyProperties(cimUser,user);

        if(!StringUtils.isEmpty(cimUser.getRegionCode())){
            UserOrg userOrg = iUserOrgService.getByUserId(userId);
            Long orgId = userOrg.getOrgId();
            Org org = iOrgService.getById(orgId);
            //是否需要迁移部门
            if(!Objects.equals(cimUser.getRegionCode(),org.getRegionCode())){
                //新部门
                OrgDTO orgDTO = getOrgByRegionCode(cimUser.getRegionCode());
                user.setUnitId(orgDTO.getUnitId());
                //删除原本部门关系
                iUserOrgService.delByUserId(userId);
                //新增新部门关系
                UserOrg newUserOrg = new UserOrg();
                newUserOrg.setUserId(userId);
                newUserOrg.setOrgId(orgDTO.getId());
                iUserOrgService.save(newUserOrg);
            }
        }
        this.updateById(user);
//        refreshRedis();

    }

    /**
     * @描述: 删除用户
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 16:50
     **/
    @Override
    public void delCimUser(User user) {
        Long userId = user.getId();
        //角色关联
        iUserRoleService.delByUserId(userId);
        //部门关联
        iUserOrgService.delByUserId(userId);
        //删除用户
        userMapper.delByUserId(userId);
    }

    /**
     * @描述: 处理默认密码
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/21 18:13
     **/
    private String getPassword(){
        String pwd = "";
        try {
            String md5 = MDUtil.getMessageDigest(DEFAULT_USER_PWD.getBytes(), "md5");
            pwd = DigestUtil.hex(md5);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            pwd = "adcd7048512e64b48da55b027577886ee5a36350";
        }
        return pwd;
    }

    /**
     * @描述: 根据行政区划获取部门，不存在即创建
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 9:14
     **/
    private OrgDTO getOrgByRegionCode(String regionCode){
        OrgDTO org = userMapper.getOrgIdByRegionCode(regionCode);
        if(org != null){
            return org;
        }
        //需创建
        OrgDTO orgDTO;
        switch (regionCode.length()) {
            case 2 : orgDTO = createOrg(regionCode,"0");break;
            case 4 : orgDTO = createOrg(regionCode,getIdByRegionCode(regionCode.substring(0,2)));break;
            case 6 : orgDTO = createOrg(regionCode,getIdByRegionCode(regionCode.substring(0,4)));break;
            case 9 : orgDTO = createOrg(regionCode,getIdByRegionCode(regionCode.substring(0,6)));break;
            default: orgDTO = createOrg(regionCode,getIdByRegionCode(regionCode));break;
        }
        return orgDTO;
    }

    /**
     * @描述: 根据行政区编码获取机构上级id，若上级不存在，则挂为顶级
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 11:08
     **/
    private String getIdByRegionCode(String regionCode){
        OrgVO orgVO = userMapper.getOrgIdByRegionCode(regionCode);
        if(orgVO != null && orgVO.getId() != null){
            return String.valueOf(orgVO.getId());
        }else {
            List<OrgDTO> orgList = userMapper.listUnitTree();
            Long unitId = 0L;
            for(OrgVO unitVO : orgList){
                if(regionCode.startsWith(unitVO.getRegionCode())){
                    unitId = unitVO.getId();
                    break;
                }
            }
            return String.valueOf(unitId);
        }
    }

    /**
     * @描述: 创建部门，若上级不存在，则挂为机构
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 11:08
     **/
    private OrgDTO createOrg(String regionCode, String parentId){
        Org org = new Org();
        Integer maxSort = userMapper.getMaxSort("SYS_ORG");
        org.setSort(maxSort + 1);
        org.setOrgCode("CIM-" + String.format("%03d",(maxSort + 1)));
        org.setCategory(1);
        org.setStatus(1);
        org.setRegionCode(regionCode);
        RegionVO regionVO = userMapper.findRegionByCode(regionCode);
        org.setOrgName(StringUtils.isEmpty(regionVO.getRegionName()) ? regionCode : regionVO.getRegionName());

        List<OrgDTO> orgList = userMapper.listUnitTree();
        Long unitId = 1365226728219213825L;
        for(OrgVO orgVO : orgList){
            if(regionCode.startsWith(orgVO.getRegionCode())){
                unitId = orgVO.getId();
                break;
            }
        }
        org.setUnitId(unitId);
        org.setParentId(Long.valueOf(parentId));
        iOrgService.save(org);
        OrgDTO saveOrg = userMapper.getOrgIdByRegionCode(org.getRegionCode());
        saveOrg.setRegionName(org.getOrgName());
        return saveOrg;
    }

    /**
     * @描述: 刷新缓存
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/4/23 16:30
     **/
    @Override
    public void refreshRedis() {
        try {
            NacosCustomConfig nacosCustomConfig = SpringUtil.getBean(NacosCustomConfig.class);
            HttpRequester httpRequester = new HttpRequester();
            Object object = httpRequester.sendPost(nacosCustomConfig.getGatewayUrl() + this.DEFAULT_REFRESH_REDIS);

            System.out.println("缓存刷新成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("缓存刷新失败");
        }
    }


    /**
     * @描述: 鉴权，如果已存在即返回，不存在就新增后返回
     * @入参:
     * @出参:
     * @作者: lzy
     * @日期: 2023/7/18 16:15
     **/
    @Override
    public String authentication(String account, String regionCode){
        if(StringUtils.isEmpty(account)){
            return null;
        }
        ApiCimUser user = userMapper.selectByAccount(account);
        if(user == null){
            user = new ApiCimUser();
            user.setAccount(account);
            user.setUserName(account);
            user.setRegionCode(regionCode);
            saveCimUser(user);
        }
        return account;
    }

}
